package com.jqsoft.launcher.activity.fragment;

import android.app.Fragment;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Base64;
import android.view.LayoutInflater;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.garea.medical.ecg.IEcg;
import com.garea.yd.util.player.IGPlayer;
import com.garea.yd.util.player.OnPlayerListener;
import com.garea.yd.util.player.nodes.src.EcgFileSource;
import com.garea.yd.util.player.wave.ecg.EcgViewer;
import com.jqsoft.launcher.R;
import com.jqsoft.launcher.activity.JQActivity;
import com.jqsoft.launcher.activity.gairui.EcgData;
import com.jqsoft.launcher.common.Constant;
import com.jqsoft.launcher.util.BytesTransUtil;
import com.jqsoft.launcher.util.EcgUtil;
import com.jqsoft.launcher.util.Log;
import com.jqsoft.launcher.util.ToastUtil;
import com.jqsoft.launcher.util.Util;

import java.util.concurrent.CountDownLatch;


/**
 * 显示心电波形图的fragment
 */
public class EcgResultViewerFragment extends Fragment {
    public static final int SAVE_ECG_DATA_FINISHED = 10000;
    public static final int SAVE_ECG_DATA_FAILED = 10001;

    private TextView txtRHr, txtQRS, txtPR, txtQtQtc;
    private TextView txtPT, txtRv5Sv1, txtRv5pSv1, txtPWidth;
    private LinearLayout layRItems;

    private volatile EcgViewer mViewer;

    private EcgData mEcgData;

    private Thread saveEcgDataThread;
    private Thread countDownLatchThread, awaitLatchThread;
	private volatile CountDownLatch latch = new CountDownLatch(1);
	private volatile boolean isPlaying = false;
    public volatile boolean canEcgPlayEnd = false;

    private TextView tvHp, tvLp, tvNotch;
    private View ecg_I;
    private View ecg_II;
    private View ecg_III;
    private View ecg_aVF;
    private View ecg_aVL;
    private View ecg_aVR;
    private View ecg_V1;
    private View ecg_V2;
    private View ecg_V3;
    private View ecg_V4;
    private View ecg_V5;
    private View ecg_V6;
    private TextureView tv1;
    private TextureView tv2;
    private LinearLayout llbackground;

    public EcgResultViewerFragment() {
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int what = msg.what;
            switch (what) {
                case SAVE_ECG_DATA_FINISHED:
                    Log.e("chenxu", "save ecg data successfully");
                    dismissProgressBar();
                    play();
                    break;
                case SAVE_ECG_DATA_FAILED:
                    dismissProgressBar();
                    ToastUtil.showToast(getActivity(), "保存心电数据失败");
                    break;
                default:
                    break;
            }
        }
    };

    private void dismissProgressBar() {
        JQActivity activity = (JQActivity) getActivity();
        activity.dismissrogressBar();
    }

    public void testThrowException(View view){
        if (view!=null){
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    throw new NullPointerException();
                }
            });
        }
    }

    public void initView() {
        View mContainer = this.getView();
        txtRHr = (TextView) mContainer.findViewById(R.id.txtEcgRHr);
        txtQRS = (TextView) mContainer.findViewById(R.id.txtEcgRQrs);
        txtPR = (TextView) mContainer.findViewById(R.id.txtEcgRPr);
        txtQtQtc = (TextView) mContainer.findViewById(R.id.txtEcgRQTQTc);
        txtPT = (TextView) mContainer.findViewById(R.id.txtEcgRPQRST);
        txtRv5Sv1 = (TextView) mContainer.findViewById(R.id.txtEcgRRV5oSV1);
        txtRv5pSv1 = (TextView) mContainer.findViewById(R.id.txtEcgRRV5aSV1);
        txtPWidth = (TextView) mContainer.findViewById(R.id.txtEcgRPWidth);

        tvHp = (TextView) mContainer.findViewById(R.id.tv_ecg_res_hp);
        tvLp = (TextView) mContainer.findViewById(R.id.tv_ecg_res_lp);
        tvNotch = (TextView) mContainer.findViewById(R.id.tv_ecg_res_notch);


        layRItems = (LinearLayout) mContainer.findViewById(R.id.layEcgRDiagnoseItem);
//        testThrowException(layRItems);

        ecg_I = mContainer.findViewById(R.id.ecg_I);
        ecg_II = mContainer.findViewById(R.id.ecg_II);
        ecg_III = mContainer.findViewById(R.id.ecg_III);
        ecg_aVF = mContainer.findViewById(R.id.ecg_aVF);
        ecg_aVL = mContainer.findViewById(R.id.ecg_aVL);
        ecg_aVR = mContainer.findViewById(R.id.ecg_aVR);
        ecg_V1 = mContainer.findViewById(R.id.ecg_V1);
        ecg_V2 = mContainer.findViewById(R.id.ecg_V2);
        ecg_V3 = mContainer.findViewById(R.id.ecg_V3);
        ecg_V4 = mContainer.findViewById(R.id.ecg_V4);
        ecg_V5 = mContainer.findViewById(R.id.ecg_V5);
        ecg_V6 = mContainer.findViewById(R.id.ecg_V6);
        tv1 = (TextureView) mContainer.findViewById(R.id.textView1);
        tv2 = (TextureView) mContainer.findViewById(R.id.textView2);
        llbackground = (LinearLayout) mContainer.findViewById(R.id.ll_viewer_background);

        mViewer = (EcgViewer) mContainer.findViewById(R.id.ecg_viewer);
        mViewer.setPlayerListener(new OnPlayerListener() {

            @Override
            public void onPaused() {
                Log.d("chenxu", "ecg viewer paused");
            }

            @Override
            public void onPlaying() {
            }

            @Override
            public void onPrepared() {
            }

            @Override
            public void onStateChanged(IGPlayer.GPlayerState oState, IGPlayer.GPlayerState nState) {
                if (oState == IGPlayer.GPlayerState.IDLE
                        && nState == IGPlayer.GPlayerState.INNITIALIZED) {
                    Log.d("chenxu", "oState is idle, nState is initialized");
					startCountDownThread();
//                    doEcgViewerPlay();
//					mViewer.play();
                } else if (nState == IGPlayer.GPlayerState.COMPLETE){
                    canEcgPlayEnd = true;
                    Log.d("chenxu", "nState is complete");
                } else if (nState == IGPlayer.GPlayerState.STOPPING){
                    Log.d("chenxu", "nState is stopping");
                } else if (nState == IGPlayer.GPlayerState.STOPPED){
                    Log.d("chenxu", "nState is stopped");
                }
                else if ((nState == IGPlayer.GPlayerState.END) || (nState == IGPlayer.GPlayerState.ERROR)){
                    Log.d("chenxu", "nState is end or error");
                }
            }

            @Override
            public void onStopped() {
                Log.d("chenxu", "ecg viewer stopped");
            }
        });
    }

    private void doEcgViewerPlay() {
//        if (mViewer.getState() != IGPlayer.GPlayerState.IDLE) {
//            mViewer.play();
//        }

//		if (!isPlaying){
//			if (mViewer.getState() != IGPlayer.GPlayerState.IDLE) {
//				isPlaying=true;
//				mViewer.play();
//			}
//		}
        startAwaitLatchThread();
    }

    private void startCountDownThread() {
        stopCountDownLatchThread();
        countDownLatchThread = new Thread(new Runnable() {
            @Override
            public void run() {
//                Log.e("chenxu", "before latch.countDown");
                latch.countDown();
//                Log.e("chenxu", "after latch.countDown");
            }
        });
        countDownLatchThread.start();
    }

    private void startAwaitLatchThread() {
        stopAwaitLatchThread();
        awaitLatchThread = new Thread(new Runnable() {
            @Override
            public void run() {
//                if (!isPlaying){
                    try {
//                        Log.e("chenxu", "before latch.await");
                        latch.await();
//                        Log.e("chenxu", "after latch.await");
//                        getActivity().runOnUiThread(new Runnable() {
//                            @Override
//                            public void run() {
//                                Log.e("chenxu", "mViewer.getState is: "+mViewer.getState());

                                synchronized (EcgResultViewerFragment.this) {
//                                if (mViewer.getState() != IGPlayer.GPlayerState.IDLE) {
//                                    Log.e("chenxu", "in doEcgViewerPlay(), call mViewer.play()");
                                    isPlaying = true;
                                    mViewer.play();
//                                }
                                }

//                            }
//                        });

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
//                } else {
//                    Log.e("chenxu", "in doEcgViewerPlay(), isPlaying is true");
//                }

            }
        });
        awaitLatchThread.start();
    }

    private void play() {
        String filePath = EcgUtil.getSavedFilePath(getActivity(), Constant.ECG_FILE_NAME);
        if (filePath != null) {
//			set6LeadMode(mEcgData.getDataLead());
            synchronized (this) {
                mViewer.setDataSource(new EcgFileSource(10, 12, 500, filePath));
            }

//            IGPlayer.GPlayerState state = mViewer.getState();
//            Log.e("chenxu", "in play(), state:" + state.ordinal());

            doEcgViewerPlay();

//			if (mViewer.getState() != IGPlayer.GPlayerState.IDLE && mViewer.getState() != IGPlayer.GPlayerState.ERROR) {
//			if (mViewer.getState() != IGPlayer.GPlayerState.IDLE) {
//				Log.e("chenxu", "in play(), call mViewer.play()");
//			    mViewer.play();
//			}
        } else {
            ToastUtil.showToast(getActivity(), "心电文件未下载保存成功");
        }
//		if (mEcgData.getDataUri() != null) {
////			set6LeadMode(mEcgData.getDataLead());
//			mViewer.setDataSource(new EcgFileSource(10, 12, 500, mEcgData.getDataUri()));
//
//			if (mViewer.getState() != GPlayerState.IDLE) {
//				mViewer.play();
//			}
//		}
    }

    public void initResult() {
        Bundle bundle = getArguments();
        if (bundle == null) {
            return;
        }
        EcgData ed = new EcgData();
        String hp = bundle.getString("hp");
        String lp = bundle.getString("lp");
        String notch = bundle.getString("notch");
        String hr = bundle.getString("hr");
        String pWidth = bundle.getString("pWidth");
        String qrsDuration = bundle.getString("qrs");
        String rv5 = bundle.getString("rv5");
        String sv1 = bundle.getString("sv1");
        String prInterval = bundle.getString("pr");
        String rv5sv1 = bundle.getString("rv5sv1");
        String qtd = bundle.getString("qtd");
        String qtc = bundle.getString("qtc");
        String pAxis = bundle.getString("pAxis");
        String qrsAxis = bundle.getString("qrsAxis");
        String taxis = bundle.getString("tAxis");
        String sECGResult = bundle.getString("sECGResult");
        String sECGData = bundle.getString("sECGData");
        ed.setHp(Util.getIntFromString(hp));
        ed.setLp(Util.getIntFromString(lp));
        ed.setNotch(Util.getIntFromString(notch));
        ed.setHr(Util.getFloatFromString(hr));
        ed.setpWidth(Util.getFloatFromString(pWidth));
        ed.setQrsDuration(Util.getFloatFromString(qrsDuration));
        ed.setRv5(Util.getFloatFromString(rv5));
        ed.setSv1(Util.getFloatFromString(sv1));
        ed.setPrInterval(Util.getFloatFromString(prInterval));
        ed.setRv5sv1(Util.getFloatFromString(rv5sv1));
        ed.setQtd(Util.getFloatFromString(qtd));
        ed.setQtc(Util.getFloatFromString(qtc));
        ed.setpAxis(Util.getFloatFromString(pAxis));
        ed.setQrsAxis(Util.getFloatFromString(qrsAxis));
        ed.setTaxis(Util.getFloatFromString(taxis));
        setEcgData(ed);

        stopSaveEcgDataThread();
        final byte[] buffer = Base64.decode(sECGData, Base64.NO_WRAP);
        saveEcgDataThread = new Thread(new Runnable() {
            @Override
            public void run() {
                boolean isSuccess = EcgUtil.writeBytesToFileName(getActivity(), Constant.ECG_FILE_NAME, buffer);
                if (isSuccess) {
                    handler.sendEmptyMessage(SAVE_ECG_DATA_FINISHED);
                } else {
                    handler.sendEmptyMessage(SAVE_ECG_DATA_FAILED);
                }
            }
        });
        saveEcgDataThread.start();

        txtRHr.setText(Integer.toString((int) mEcgData.getHr()) + "bpm");
        txtQRS.setText(Integer.toString((int) mEcgData.getQrsDuration()) + "ms");
        txtPR.setText(Integer.toString((int) mEcgData.getPrInterval()) + "ms");
        txtQtQtc.setText(Integer.toString((int) mEcgData.getQtd()) + "ms/" + Integer.toString((int) mEcgData.getQtc()) + "ms");
        txtPT.setText(Integer.toString((int) mEcgData.getPAxis()) + "度/" + Integer.toString((int) mEcgData.getQrsAxis()) + "度/" + Integer.toString((int) mEcgData.getTAxis()) + "度");
        txtRv5Sv1.setText(Float.toString(Math.abs(mEcgData.getRv5())) + "mV/" + Float.toString(Math.abs(mEcgData.getSv1())) + "mV");
        txtRv5pSv1.setText(Float.toString(mEcgData.getRv5sv1()) + "mV");
        txtPWidth.setText(Integer.toString((int) mEcgData.getPWidth()) + "ms");

        layRItems.removeAllViews();
        LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        TextView txtMsg = new TextView(this.getActivity());
        txtMsg.setText(sECGResult);
        txtMsg.setTextColor(Color.BLACK);
        txtMsg.setTextSize(20);
        txtMsg.setLayoutParams(param);
        layRItems.addView(txtMsg);

//		for (String rText : mEcgData.getResultText()) {
//			TextView txtMsg = new TextView(this.getActivity());
//			txtMsg.setText(rText);
//			txtMsg.setTextColor(Color.BLACK);
//			txtMsg.setTextSize(20);
//			txtMsg.setLayoutParams(param);
//			layRItems.addView(txtMsg);
//		}
    }

    private short[] getShortArrayFromByteArray(byte[] byteArray) {
        if (byteArray == null) {
            return new short[0];
        }
        BytesTransUtil bytesTransUtil = BytesTransUtil.getInstance();
        short[] shortArray = bytesTransUtil.Bytes2Shorts(byteArray);
        return shortArray;
    }


    private void stopSaveEcgDataThread() {
        try {
            if (saveEcgDataThread != null && saveEcgDataThread.isAlive()) {
                saveEcgDataThread.interrupt();
            }
            saveEcgDataThread = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void stopCountDownLatchThread(){
        try {
            if (countDownLatchThread!=null && countDownLatchThread.isAlive()){
                countDownLatchThread.interrupt();
            }
            countDownLatchThread=null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void stopAwaitLatchThread(){
        try {
            if (awaitLatchThread != null && awaitLatchThread.isAlive()){
                awaitLatchThread.interrupt();
            }
            awaitLatchThread = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void initConfig() {

        switch (mEcgData.getHp()) {
            case IEcg.ECG_FILTER_HP_005:
                tvHp.setText("0.05Hz");
                break;
            case IEcg.ECG_FILTER_HP_015:
                tvHp.setText("0.15Hz");
                break;
            case IEcg.ECG_FILTER_HP_025:
                tvHp.setText("0.25Hz");
                break;
            case IEcg.ECG_FILTER_HP_050:
                tvHp.setText("0.50Hz");
                break;
            default:
                tvHp.setText("关闭");
                break;
        }

        switch (mEcgData.getLp()) {
            case IEcg.ECG_FILTER_LP_20HZ:
                tvLp.setText("20Hz");
                break;
            case IEcg.ECG_FILTER_LP_30HZ:
                tvLp.setText("30Hz");
                break;
            case IEcg.ECG_FILTER_LP_40HZ:
                tvLp.setText("40Hz");
                break;
            default:
                tvLp.setText("关闭");
                break;
        }

        switch (mEcgData.getNotch()) {
            case IEcg.ECG_FILTER_NOTCH_50HZ:
                tvNotch.setText("50Hz");
                break;
            case IEcg.ECG_FILTER_NOTCH_60HZ:
                tvNotch.setText("60Hz");
                break;
            default:
                tvNotch.setText("关闭");
                break;
        }
    }


    public void setEcgData(EcgData ecg) {
        mEcgData = ecg;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//		View view = setContentView(inflater, R.layout.g_ecg_result, container);
        View view = inflater.inflate(R.layout.g_ecg_result, container, false);


//		this.setButtonVisiable(ParentFragmentInterface.BACK_BUTTON, false);
//		this.setButtonVisiable(ParentFragmentInterface.NEXT_BUTTON, false);
//		this.setButtonVisiable(ParentFragmentInterface.REPORT_BUTTON, false);
//		this.setButtonVisiable(ParentFragmentInterface.SAVE_BUTTON, false);
//		this.setButtonVisiable(ParentFragmentInterface.GO_BACK_BUTTON, true);


        return view;
    }

    @Override
    public void onActivityCreated(/*@Nullable */Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initView();
        initResult();
        initConfig();


    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        stopRunningThreadsAndReleaseEcgViewer();
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
//		this.setButtonVisiable(ParentFragmentInterface.GO_BACK_BUTTON, false);
//		this.setButtonVisiable(ParentFragmentInterface.BACK_BUTTON, true);

        stopRunningThreadsAndReleaseEcgViewer();
    }

    private void stopRunningThreadsAndReleaseEcgViewer() {
        stopSaveEcgDataThread();
        stopCountDownLatchThread();
        stopAwaitLatchThread();
        releaseEcgViewer();
    }



    private void releaseEcgViewer() {
        if (mViewer != null) {
            synchronized (this) {
                mViewer.stop();
                mViewer.release();
                mViewer = null;
            }
        }

    }

    /**
     * 设置显示3导心电图的模式
     */
    public void set6LeadMode(int leadMode) {
        if (leadMode == 6) {//如果是3导 就调整UI
            ecg_V1.setVisibility(View.GONE);
            ecg_V1.setTag("");
            ecg_V2.setVisibility(View.GONE);
            ecg_V2.setTag("");
            ecg_V3.setVisibility(View.GONE);
            ecg_V3.setTag("");
            ecg_V4.setVisibility(View.GONE);
            ecg_V4.setTag("");
            ecg_V5.setVisibility(View.GONE);
            ecg_V5.setTag("");
            ecg_V6.setVisibility(View.GONE);
            ecg_V6.setTag("");
            tv1.getLayoutParams().height /= 2;
            tv2.getLayoutParams().height /= 2;
            llbackground.setPadding(llbackground.getPaddingLeft(), llbackground.getPaddingTop(),
                    llbackground.getPaddingRight(), 0);
        }
    }
}
